#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# File Name: h264Toh265.py
# Author: bobo
# Created Time: 20231202
"""
硬编码转换脚本，H264->HEVC
Usage:
    h264Toh265.py -f <files>... [-l=<level>] [--out=<outdir>] [-d] [--h265] [--para=<para>] [--suffix=<suffix>] [--fmt=<fmt>]
    h264Toh265.py (-h | --help)
    h264Toh265.py (-v | --version)

Options:
    -h --help  显示帮助信息
    -v  --version  显示版本信息
    <files> 要处理的文件
    -l <lever> 视频质量（18～50）
    -d  删除原文件
    --h265  转换成H265格式文件
    --out=<outdir> 输出视频路径
    --para=<para>  额外参数，推荐的最小值是-b 0.6M -minrate 0.4M -maxrate 2M -bufsize 4M，最大2M,1M,4M,8M; -vf 'transpose=1'
    --suffix=<suffix> 输出文件增加后缀
    --fmt=<fmt> 输入文件格式
"""

import glob
import os

from docopt import docopt

FFMPEG_PATH = "/usr/lib/jellyfin-ffmpeg/ffmpeg"
CMD_PREFIX = f"sudo {FFMPEG_PATH} -hwaccel qsv -i "

# ####### H265 ########
# FFMPEG_PARAM = "-c:v hevc_qsv -c:a copy"  #hevc_qsv硬编码
# FFMPEG_PARAM = "-c:v libx265 -c:a copy -b:v 5M"  #libx265软编码
# -r 8是指定视频的帧率,建议设置在5--30之间
# 推荐的最小值是-b 0.6M -minrate 0.4M -maxrate 2M -bufsize 4M
# 最大值是-b 2M -minrate 1M -maxrate 4M -bufsize 8M
# NEW_SUFFIX = "_hevc-libx265"
#######################################

# crf 是H264的选项
# crf 21-1M
# -map 0:v -map 0:a -map 0:s

# ---------------------------
# mkv文件，H264多音轨+多字幕 -> hevc+多音轨+集成一个字幕，没有实现多字幕
#  FFMPEG_PARAM = '-map 0:v -c:v hevc_qsv -preset fast -global_quality 21 \
#          -map 0:a -c:a aac \
#          -map 0:s:0  -map 0:s:29 -c:s copy'
# NEW_SUFFIX = "_hevc-acc(中英文字幕)"
# ---------------------------
# FFMPEG_PARAM = '-c:v hevc_qsv -preset fast -global_quality 21 -look_ahead 1 \
#        -filter_complex "[0:v][0:s]overlay[v]" -map "[v]" \
#        -c:a copy  -map 0:a'
# NEW_SUFFIX = "_hevc-21"
# ---------------------------
# mkv文件，H264+EAC3 -> hevc+AAC+删除字幕
# ---------------------------
# sudo $cmd -i $urlfix/第04期下/index.m3u8  \
# -c:v hevc_qsv -bsf:a aac_adtstoasc \
# $prefix-08-第04期下.mp4
# ---------------------------
# ffmpeg -hwaccel qsv -i SVID_20240510_225956_1.mp4 \
# -c:v hevc_qsv -preset fast -global_quality 22 \
# -c:a aac \
# out111.mp4
# ---------------------------
#  FFMPEG_PARAM = '-c:v hevc_qsv -preset fast -global_quality 21 -c:a copy'
# H265
FFMPEG_PARAM = "-c:v ENCODE -preset fast -global_quality LEVEL -c:a aac -map_metadata 0"

PERMISSION = "bongem:bongem"
VIDEO_SUFFIX = "*.[mr][pmk][4v]*"


def get_ffmpeg_param():
    print(arguments)

    path = arguments.get("--out")
    out_dir = path if path else None

    name_suffix = arguments.get("--suffix") or "_new"

    fmt = arguments.get("--fmt")
    fmt = fmt if fmt else None

    encode = "hevc_qsv" if arguments.get("--h265") else "h264_qsv"
    ffmpeg_param = FFMPEG_PARAM.replace("ENCODE", encode)

    level = arguments.get("-l")
    level = int(level) if level else 21
    ffmpeg_param = ffmpeg_param.replace("LEVEL", str(level))

    if exra_para := arguments.get("--para"):
        ffmpeg_param = ffmpeg_param + " " + exra_para

    return ffmpeg_param, out_dir, name_suffix, fmt


def convert(src_file):
    """转换H264为HEVC"""
    _param, out_dir, name_suffix, fmt = get_ffmpeg_param()

    filedir = os.path.dirname(src_file)
    filename = os.path.basename(src_file)
    pos = filename.rfind(".")
    name = filename[:pos]
    format = "." + fmt if fmt else filename[pos:]
    # print(f'[{filedir}] [{name}] [{format}]')
    # print(new_file)

    new_file = os.path.join(
        out_dir if out_dir else filedir, name + name_suffix + format
    )
    convert_cmd = f'{CMD_PREFIX} "{src_file}" {_param} "{new_file}"'
    print(convert_cmd)
    os.system(convert_cmd)
    os.system(f'sudo chown {PERMISSION} "{new_file}"')


def main(name):
    """主函数"""
    if os.path.isfile(name):
        convert(name)
    elif os.path.isdir(name):
        #  name = name.replace('[', '\[')
        #  name = name.replace(']', '\]')
        #  name = name.replace('\[', '[[]')
        #  name = name.replace('\]', '[]]')
        f = os.path.join(glob.escape(name), VIDEO_SUFFIX)
        print("Dir:", f)
        video_lst = glob.glob(f)
        print(video_lst)
        video_lst.sort()
        for video in video_lst:
            convert(video)
    else:
        raise Exception("目录或文件错误。")


if __name__ == "__main__":
    arguments = docopt(__doc__, version="h264Toh265 1.0")

    if infiles := arguments.get("<files>"):
        print(f"video files：{infiles}")
    else:
        print(__doc__)
        exit()
    # if len(sys.argv) != 2:
    #    print("usage: ./h264Toh265.py  fiel|dir")
    #    sys.exit(1)

    try:
        for f in infiles:
            print(f"file:{f}")
            main(f)
    except Exception as e:
        print(f"错误：{e}")
